home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
t3_1
/
risc_src.lha
/
risc_sources
/
link
/
sparc_link.t
< prev
next >
Wrap
Text File
|
1989-07-06
|
12KB
|
320 lines
(herald sparc_link (env t (link defs)))
(define (define-null-descriptor heap)
(modify (area-frontier heap)
(lambda (x) (fx+ (fx+ x %%slink-size) %%stack-size)))
(set *null-descriptor*
(object nil
((heap-stored self) heap)
((heap-offset self) (fx+ %%stack-size tag/pair))
((write-descriptor self stream)
(write-data stream (fx+ %%stack-size tag/pair)))
((write-store self stream)
(do ((i 0 (fx+ i 4)))
((fx= i %%stack-size))
(write-int stream 0))
(let ((pi (fx+ slink/initial-pure-memory-begin 3)))
(do ((i 0 (fx+ i 4)))
((fx= i pi)
(write-int stream 0)
(write-int stream (area-frontier (lstate-pure *lstate*)))
(write-data stream %%stack-size)
(write-data stream (area-frontier (lstate-impure *lstate*)))
(do ((i (fx+ i 16) (fx+ i 4)))
((fx= i %%slink-size))
(write-int stream 0)))
(write-int stream 0))))))
(push (area-objects heap) *null-descriptor*)
(set-table-entry *reloc-table* nil *null-descriptor*)
(reloc-thunk (object nil
((heap-stored self) (lstate-pure *lstate*))
((write-descriptor self stream)
(write-int stream 0)))
(fx+ %%stack-size
(fx+ slink/initial-pure-memory-begin 3)))
(reloc-thunk (object nil
((heap-stored self) (lstate-pure *lstate*))
((write-descriptor self stream)
(write-int stream (area-frontier (lstate-pure *lstate*)))))
(fx+ %%stack-size (fx+ slink/initial-pure-memory-end 3)))
(reloc-thunk (object nil
((heap-stored self) (lstate-impure *lstate*))
((write-descriptor self stream)
(write-data stream %%stack-size)))
(fx+ %%stack-size
(fx+ slink/initial-impure-memory-begin 3)))
(reloc-thunk (object nil
((heap-stored self) (lstate-impure *lstate*))
((write-descriptor self stream)
(write-data stream (area-frontier (lstate-impure *lstate*)))))
(fx+ %%stack-size
(fx+ slink/initial-impure-memory-end 3))))
(define (vgc-copy-vcell vcell)
(let* ((heap (lstate-impure *lstate*))
(addr (area-frontier heap))
(var (vcell-struct-var vcell))
(desc (object nil
((heap-stored self) (lstate-impure *lstate*))
((heap-offset self) addr)
((write-descriptor self stream)
(write-data stream (fx+ addr tag/extend)))
((write-store self stream)
(write-vcell-header var stream)
(write-var-ref stream var)
(write-data stream (fx+ addr 22))
(write-slot (var-node-name var) stream)
(write-data stream (fx+ addr 30))
(write-int stream header/weak-alist)
(write-slot (var-node-refs var) stream)
(write-int stream header/weak-alist)
(write-slot (var-node-vcell-refs var) stream)))))
(set (area-frontier heap) (fx+ addr (fx* CELL 9))) ; 5 for vcell
(set-table-entry *reloc-table* vcell desc) ; 4 for weak-alists
(push (area-objects heap) desc)
(relocate-unit-variable var (fx+ addr CELL) t)
(set (var-node-refs var) (a-list->vector (var-node-refs var)))
(set (var-node-vcell-refs var) (a-list->vector (var-node-vcell-refs var)))
(generate-slot-relocation (var-node-refs var) (fx+ addr (fx* CELL 6)))
(generate-slot-relocation (var-node-vcell-refs var) (fx+ addr (fx* CELL 8)))
(generate-slot-relocation (var-node-name var) (fx+ addr (fx* CELL 3)))
(reloc-thunk (object nil
((heap-stored self) (lstate-impure *lstate*))
((write-descriptor self stream)
(write-data stream (fx+ addr 22))))
(fx+ addr (fx* CELL 2)))
(reloc-thunk (object nil
((heap-stored self) (lstate-impure *lstate*))
((write-descriptor self stream)
(write-data stream (fx+ addr 30))))
(fx+ addr (fx* CELL 4)))
desc))
;;; Look at a Unix a.out description and template.doc
(define (link modules out-spec)
(really-link modules 'so out-spec 'o))
(define-constant %%d-ieee-size 53)
(define-constant %%d-ieee-excess 1023)
(define (write-double-float stream float)
(receive (sign mantissa exponent)
(normalized-float-parts float
%%d-ieee-size
%%d-ieee-excess
t)
(write-int stream header/double-float)
(write-half stream (fx+ (fixnum-ashl sign 15)
(fx+ (fixnum-ashl exponent 4)
(bignum-bit-field mantissa 48 4))))
(write-half stream (bignum-bit-field mantissa 32 16))
(write-half stream (bignum-bit-field mantissa 16 16))
(write-half stream (bignum-bit-field mantissa 0 16))))
(define (write-vcell-header var stream)
(write-half stream 0)
(write-byte stream (if (fx= (vector-length (var-node-refs var))
0)
0
-1))
(write-byte stream (if (eq? (var-node-defined var) 'define)
(fx+ header/vcell 128)
header/vcell)))
(define-constant RELOC-SIZE 12)
(define-constant CYMBAL-SIZE 12)
(define-constant OMAGIC #o407)
(define-constant N_TEXT 4)
(define-constant N_DATA 6)
(define-constant N_UNDF 0)
(define-constant N_EXT 1)
(define (vgc-copy-foreign foreign)
(let* ((heap (lstate-impure *lstate*))
(addr (area-frontier heap))
(name (foreign-object-name foreign))
(desc (object nil
((heap-stored self) (lstate-impure *lstate*))
((heap-offset self) addr)
((write-descriptor self stream)
(write-data stream (fx+ addr tag/extend)))
((write-store self stream)
(write-int stream header/foreign)
(write-slot name stream)
(write-int stream 0)))))
(set (area-frontier heap) (fx+ addr 12))
(set-table-entry *reloc-table* foreign desc)
(generate-slot-relocation name (fx+ addr 4))
(push (area-objects heap) desc)
(cymbal-thunk (string-append "_" (symbol->string name))
(fixnum-logior N_UNDF N_EXT) 0)
(reloc-thunk (fixnum-logior (fixnum-ashl (lstate-symbol-count *lstate*) 8)
#x82)
(fx+ addr 8))
(modify (lstate-symbol-count *lstate*) (lambda (x) (fx+ x 1)))
desc))
(define (relocate-unit-variable var addr external?)
(let ((area (lstate-impure *lstate*))
(type (var-value-type var)))
(cond (type
(cond ((and external? (neq? (var-node-value var) NONVALUE))
(cymbal-thunk (string-downcase! (symbol->string (var-node-name var)))
(fixnum-logior N_DATA N_EXT)
(unit-var-value (var-node-value var)))
(modify (lstate-symbol-count *lstate*) (lambda (x) (fx+ x 1)))))
(reloc-thunk type addr)))))
(define (var-value-type var)
(let ((value (var-node-value var)))
(cond ((eq? value NONVALUE)
(vgc (var-node-name var))
nil)
((unit-loc? value) value)
(else (vgc value)))))
(define (generate-slot-relocation obj slot-address)
(cond ((or (fixnum? obj) (char? obj) (eq? obj '#t)))
(else
(reloc-thunk (vgc obj) slot-address))))
(define (reloc-thunk type address)
(push (lstate-data-reloc *lstate*)
(cons address type)))
(define (cymbal-thunk stryng type value)
(push (lstate-symbols *lstate*)
(object (lambda (stream a)
;; a is offset into stryng table
(write-int stream a)
(write-byte stream type)
(write-byte stream 0) ; other
(write-half stream 0) ; see <stab.h>
(if (fx= type 1) ; undefined external (foreign)
(write-int stream 0)
(write-data stream value)))
((cymbal-thunk.stryng self) stryng))))
(define-operation (cymbal-thunk.stryng thunk))
(lset pure-size nil)
(define (write-slot obj stream)
(cond ((table-entry *reloc-table* obj)
=> (lambda (desc) (write-descriptor desc stream)))
((fixnum? obj)
(write-fixnum stream obj))
((char? obj)
(write-int stream (fx+ (fixnum-ashl (char->ascii obj) 8)
header/char)))
((eq? obj '#t)
(write-int stream header/true))
(else
(error "bad immediate type ~s" obj))))
(define-integrable (write-data stream int)
(write-int stream (fx+ pure-size int)))
(define-integrable (write-int stream int)
(write-half stream (fixnum-ashr int 16))
(write-half stream int))
(define (write-half stream int)
(write-byte stream (fixnum-ashr int 8))
(write-byte stream int))
(define-integrable (write-byte stream n)
(writec stream (ascii->char (fixnum-logand n 255))))
(define-integrable (write-fixnum stream fixnum)
(write-half stream (fixnum-ashr fixnum 14))
(write-half stream (fixnum-ashl fixnum 2)))
(define (write-link-file stream)
(pad-area (lstate-pure *lstate*))
(pad-area (lstate-impure *lstate*))
(set pure-size (area-frontier (lstate-pure *lstate*)))
(write-header stream)
(write-area stream (lstate-pure *lstate*))
(write-area stream (lstate-impure *lstate*))
(write-relocation stream (lstate-data-reloc *lstate*))
(write-cymbal&stryng-table stream (reverse (lstate-symbols *lstate*))))
(define (write-header stream)
(let* ((text-size (area-frontier (lstate-pure *lstate*)))
(data-size (area-frontier (lstate-impure *lstate*))))
(write-half stream #x0103) ; only on sparc
(write-half stream OMAGIC) ;magic number
(write-int stream text-size) ;text segment size
(write-int stream data-size) ;data segment size
(write-int stream 0) ;bss segment size
(write-int stream (fx* CYMBAL-SIZE (lstate-symbol-count *lstate*)))
(write-int stream 0) ;bogus entry point
(write-int stream 0) ; no text relocation
(write-int stream (fx* (length (lstate-data-reloc *lstate*)) RELOC-SIZE))))
(define (write-area stream area)
(walk (lambda (x) (write-store x stream))
(reverse! (area-objects area))))
(define (write-relocation stream items)
(walk (lambda (item)
(let ((addr (car item))
(desc (cdr item)))
(write-int stream (car item))
(cond ((fixnum? desc)
(write-int stream desc)
(write-int stream 0))
((unit-loc? desc)
(write-int stream #x602)
(write-unit-loc stream desc))
((eq? (heap-stored desc) (lstate-pure *lstate*))
(write-int stream #x402)
(write-descriptor desc stream))
(else
(write-int stream #x602)
(write-descriptor desc stream)))))
(sort-list! items
(lambda (x y)
(fx< (car x) (car y))))))
(define (write-map-entry stream name value) nil)
(define (write-cymbal&stryng-table stream cyms)
(let ((z (write-cyms stream cyms))) ; cymbal table
(write-int stream z) ; size of stryng table
(walk (lambda (s) ; write stryng table
(write-string stream (cymbal-thunk.stryng s))
(write-byte stream 0))
cyms)))
(define (write-cyms stream cyms)
(iterate loop ((a 4) ;; 4 bytes for size of stryng table
(l cyms))
(cond ((null? l) a)
(else
(let ((e (car l)))
(e stream a)
(loop (fx+ (fx+ a (string-length (cymbal-thunk.stryng e))) 1) ;null
(cdr l)))))))
(define (pad-area area)
(let ((rem (fixnum-remainder (area-frontier area) 16)))
(cond ((fxn= rem 0)
(modify (area-frontier area)
(lambda (x) (fx+ x (fx- 16 rem))))
(do ((i (fx- 16 rem) (fx- i 4)))
((fx= i 0))
(push (area-objects area)
(object nil
((write-store self stream)
(write-int stream 0)))))))))